#include "uiBase.h"

#include <Poco/String.h>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include "uiList.h"
#include "uiInfo.h"
#include "uiFiles.h"
#include "misc/Interface.h"
#include "misc/Event.h"
#include "server/misc/Config.h"
/*********************************************************/
uiBase* uiBase::parse(const std::string& cmd)
{
	uiBase*		command = 0;
	Interface& intf = Interface::Instance();
	std::vector<std::string> args = tokenize(cmd);

	// Check the commands one by one
	if ( Poco::icompare(args[0], "list") == 0 ) {
		command = new uiList;
	} else if ( Poco::icompare(args[0], "info") == 0 ) {
		command = new uiInfo;
	} else if ( Poco::icompare(args[0], "files") == 0 ) {
		command = new uiFiles;
	} else if ((Poco::icompare(args[0], "quit") == 0 ) || (Poco::icompare(args[0], "stop") == 0)) {
		Config& cfg = Config::Instance();
		Event* quitEvent = Event::Instance(cfg.getQuitEvent());
		quitEvent->set();

	} else if ( Poco::icompare(args[0], "?") == 0 ) {
		helpInfo();
	} else {
		intf << "Invalid command!" << std::endl;
		helpInfo();
	}

	args.erase(args.begin());
	if ( command ) {
		command->parseOptions(args);
	} else { 
		return 0;
	}

	return( command );
}
/*********************************************************/
void uiBase::helpInfo()
{
	Interface& intf = Interface::Instance();

	intf << "Command line help: " << std::endl << std::endl;
	intf << "?       : Prints this information" << std::endl;
	intf << "info    : Get information about the local network settings" << std::endl;
	intf << "list    : Get a complete overview of the current ring configuration" << std::endl;
	intf << "files   : Will display an overview of all files stored in the local repository" << std::endl;
	intf << "quit    : Stop the server" << std::endl << std::endl;
	intf << "<command> ? will display help information about <command>" << std::endl;
	intf.flush();
}
/*********************************************************/
std::vector<std::string> uiBase::tokenize(const std::string& cmd)
{
	using namespace std;

	vector<string> 		tokens, args;
	string			name, argument, opt;

	// The first part will split the string into seperate words ( white space as a delimiter )
	istringstream iss(cmd);
	copy(istream_iterator<string>(iss),istream_iterator<string>(),back_inserter<vector<string> >(tokens));

	// First token is the command
	args.push_back(tokens[0]);

	// Now we are going to group the arguments and the options together
	opt = "";
	bool first = true;
	for (unsigned int i = 1; i<tokens.size(); i++ ) {
		
		if ( tokens[i][0] == '-' ) {
			if ( !first ) {
				args.push_back(opt);
				opt.clear();
			} else {
				first = false;
			}
			opt.append(tokens[i]);
		} else {
			opt.append(" ");
			opt.append(tokens[i]);
		}
	}
	args.push_back(opt);		// push the last string on the vector

	return( args );
}
